﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace ModbusCommunicate
{
   public   class ModBus
    {

        internal  ModBus(SendModBusData SMBD)
        {
            send = SMBD;
            T = new System.Timers.Timer();
            T.Interval = 10000;
            T.Elapsed += T_Elapsed;
        }

        /// <summary>
        /// 数据是否有返回
        /// <para>0:等待数据返回</para>
        /// <para>1:正常返回</para>
        /// <para>2:返回超时</para>
        /// </summary>
        public int locks { get; set; }

        /// <summary>
        /// 开始打包发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            T.Stop();
            locks = 2;
        }

        /// <summary>
        /// 发送数据
        /// </summary>
       internal   async  void  SendModBus()
        {
            if (IsTaskStart )  return;
            IsTaskStart = true;
            while ( SendModbusMsg.Count>0)
            {
                ModbusSend MS = SendModbusMsg[0];
                SendModbusMsg.RemoveAt(0);
                string Sendmsg = Js.Serialize(MS);
                int res = await WaitCallBack(System.Text.Encoding.Default.GetBytes(Sendmsg));               
            }
            IsTaskStart = false ;
            T.Stop();
        }

    
        private Task<int>   WaitCallBack(byte[] msg)
        {
          return   Task.Run(() =>
            {
                T.Start();
                locks = 0;
                if( !send(msg))
                {
                    SendModbusMsg.Clear();
                    return 2;
                }
              if( WaitBack()==2)   //通信失败重发一次
                {
                    T.Start();
                    if (!send(msg))
                    {
                        SendModbusMsg.Clear();
                        return 2;
                    }
                    locks = 0;
                    return WaitBack();
                }
              else 
                return 1;
            });
        }

        private int   WaitBack()
        {
            while (true)
            {
                System.Threading.Thread.Sleep(1);
                if (locks > 0)
                    break; 
            }
            T.Stop();
            T.Start();
            return locks;
        }


       JavaScriptSerializer Js = new JavaScriptSerializer();

        /// <summary>
        /// 任务是否已经开始
        /// </summary>
        public bool IsTaskStart { get; set; }

        /// <summary>
        /// 调用接口发送数据
        /// </summary>
        internal  SendModBusData send;
        internal  delegate bool  SendModBusData(byte[] data);

        /// <summary>
        /// 超时时间，多长时间未返回数据则通信失败
        /// </summary>
        System.Timers.Timer T;

        /// <summary>
        /// 记录要发送的MODBUS协议集合
        /// </summary>
        List<ModbusSend> SendModbusMsg = new List<ModbusSend>();


        /// <summary>
        /// 添加一个modbus发送数据
        /// </summary>
        /// <param name="MS"></param>
        internal  void AddModBus(ModbusSend MS)
        {
            SendModbusMsg.Add(MS);
        }

        /// <summary>
        /// 移除一个modbus任务
        /// </summary>
        /// <param name="MS"></param>
        internal void RemoveModBus(ModbusSend MS)
        {
            SendModbusMsg.Remove(MS);
        }
    }
}
